package com.itheima.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.constant.RedisConstant;
import com.itheima.dao.CheckGroupDao;
import com.itheima.dao.CheckItemDao;
import com.itheima.dao.SetMealDao;
import com.itheima.entity.PageResult;
import com.itheima.pojo.CheckGroup;
import com.itheima.pojo.CheckItem;
import com.itheima.pojo.Setmeal;

import com.itheima.service.SetMealService;

import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import redis.clients.jedis.JedisPool;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*
 *@AUTHOR:LIUCHAO;
 *@DATE: 2020/9/9 19:24
 */
@Service(interfaceClass = SetMealService.class)
public class SetMealServiceImpl implements SetMealService {
    /*注入静态页面的配置类*/
    @Autowired
    private FreeMarkerConfigurer freeMarkerConfigurer;
    @Value("${out_put_path}")//从属性文件读取输出目录的路径
    private String outputpath;

    @Autowired
    private SetMealDao setMealDao;
    @Autowired
    private JedisPool jedisPool;
    @Override
    public PageResult pageQuery(Integer currentPage, Integer pageSize, String queryString) {
        PageHelper.startPage(currentPage,pageSize);
        Page<Setmeal> page=setMealDao.selectByCondition(queryString);
        return new PageResult(page.getTotal(),page.getResult());
    }

    @Override
    public List<Integer> findCheckGroupIdsBySetMealId(Integer setMealId) {

        return setMealDao.findCheckGroupIdsBySetMealId(setMealId);
    }

    @Override
    public void update(Setmeal setmeal, Integer[] checkgroupIds) {
        setMealDao.update(setmeal);
        setMealDao.deleteCheckGroupIdAndSetMealId(setmeal.getId());
        setCheckGroupAndSetMeal(setmeal.getId(),checkgroupIds);

    }

    @Override
    public void delete(Integer id) {
        //查询当前套餐是否和预约关联
        long count = setMealDao.findCountBySetMealId(id);
        if(count > 0){
            //当前检查项被引用，不能删除
            throw new RuntimeException("当前检查项被引用，不能删除");
        }
        setMealDao.deleteCheckGroupIdAndSetMealId(id);
        setMealDao.delete(id);
    }



    @Override
    public void add(Setmeal setmeal, Integer[] checkgroupIds) {
        setMealDao.add(setmeal);
        if (checkgroupIds!=null&&checkgroupIds.length>0){
            setCheckGroupAndSetMeal(setmeal.getId(),checkgroupIds);
        }
        //将图片名称保存到Redis
        savePic2Redis(setmeal.getImg());
        /*==================*/
        /*生成静态页面*//*注意,在添加和修改的时候进行静态页面的生成,现在只做了添加*/
        generateMobileStaticHtml();
        /*List<Setmeal> testList = findAll();//将方法抽出
        Map map=new HashMap();
        map.put("testList",testList);
        String templateFtl="testTemplate.ftl";
        String freeMakerPage="freeMakerPage.ftl";
        Configuration configuration = freeMarkerConfigurer.getConfiguration();
        try {
            Template template = configuration.getTemplate(templateFtl);
            FileOutputStream fos = new FileOutputStream(new File(outputpath + "/" + freeMakerPage));
            OutputStreamWriter osw = new OutputStreamWriter(fos);
            BufferedWriter bw = new BufferedWriter(osw);
            template.process(map,bw);
            bw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }*/

    }

    private void generateMobileStaticHtml() {
        List<Setmeal> setmealList = this.findAll();
        generateMobileSetmealListHtml(setmealList);
//生成套餐详情静态页面（多个）
        generateMobileSetmealDetailHtml(setmealList);
    }

    private void generateMobileSetmealDetailHtml(List<Setmeal> setmealList) {
        for (Setmeal setmeal : setmealList) {
            Map<String, Object> dataMap = new HashMap<String, Object>();
            dataMap.put("setmeal", this.findById2(setmeal.getId()));
            this.freemakerPageBytemplate(dataMap,
                    "freemaker_setmeal_detail_"+setmeal.getId()+".html", "template_setmeal_detail.ftl");
        }
    }

    private void generateMobileSetmealListHtml(List<Setmeal> setmealList) {
        Map map=new HashMap();
        map.put("setmealList",setmealList);
        /*讲一个方法 将模板传入  输出路径 和数据传入,进行页面静态化*/
       /*所有套餐页面静态化*/
        String templatePage="templateSetmeal.ftl";
        String freemakerPage="freemakerSetmeal.html";
       freemakerPageBytemplate(map,freemakerPage,templatePage);
    }

    private void freemakerPageBytemplate(Map map, String freemakerPage, String templatePage) {

        //1.创建配置类
        Configuration configuration=freeMarkerConfigurer.getConfiguration();
        Writer out =null;
        //2.设置模板所在的目录
        try {
            /*在项目中是直接将模板所在目录配置在核心配置文件中*/
//            configuration.setDirectoryForTemplateLoading(new File(outputpath));
            //3.设置字符集
            configuration.setDefaultEncoding("utf-8");
            //4.加载模板
            Template template = configuration.getTemplate(templatePage);
            //6.创建Writer对象
//             out =new FileWriter(new File(outputpath+"\\"+freemakerPage));
//            System.out.println("freemakerPage = " + outputpath + "/" + freemakerPage);
            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(outputpath+"\\"+freemakerPage))));
            //7.输出
            template.process(map, out);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //8.关闭Writer对象
        if (out!=null){
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    private void setCheckGroupAndSetMeal(Integer setMealId, Integer[] checkgroupIds) {
        if (checkgroupIds!=null&&checkgroupIds.length>0){
            for (Integer checkgroupId : checkgroupIds) {
                HashMap<String, Integer> map = new HashMap<>();
                map.put("setmeal_id",setMealId);
                map.put("checkgroup_id",checkgroupId);
                setMealDao.setCheckGroupAndSetMeal(map);
            }
        }
    }

    //将图片名称保存到Redis
    private void savePic2Redis(String pic){
        jedisPool.getResource().sadd(RedisConstant.SETMEAL_PIC_DB_RESOURCES,pic);
//        jedisPool.close();
    }


    @Override
    public List<Setmeal> findAll() {

        return setMealDao.findAll();
    }


/*    @Override
    public Setmeal findById(Integer setmealId) {
        return setMealDao.findById(setmealId);
    }*/


    @Autowired
    private CheckGroupDao checkGroupDao;
    @Autowired
    private CheckItemDao checkItemDao;


    @Override
    public Setmeal findById(Integer setmealId) {
        /*=======*/
        Setmeal setmeal = setMealDao.findById(setmealId);
        List<Integer> checkGroupIds = setMealDao.findCheckGroupIdsBySetMealId(setmealId);
        List<CheckGroup> checkGroups=new ArrayList<>();
        for (Integer checkGroupId : checkGroupIds) {
           CheckGroup checkGroupById= checkGroupDao.findById(checkGroupId);
            List<Integer> checkItemIds = checkGroupDao.findCheckItemIdsByCheckGroupId(checkGroupId);
            List<CheckItem> checkItems=new ArrayList<>();
            for (Integer checkItemId : checkItemIds) {
                CheckItem checkItem= checkItemDao.findById(checkItemId);
                checkItems.add(checkItem);
            }
            checkGroupById.setCheckItems(checkItems);
            checkGroups.add(checkGroupById);
        }
        setmeal.setCheckGroups(checkGroups);
        return setmeal;
    }
/*采用在数据库查询的方式来进行多表查询,此时不需要在pojo类中对数据进行封装,
* 直接在数据库中对数据进行操作,进行返回的时候直接返回的就是所需要的类
* 另一张表的数据直接封装成一个新的map*/
    @Override
    public Setmeal findById2(Integer setmealId) {
        /*=======*/
        return  setMealDao.findById2(setmealId);
    }

    @Override
    public List<String> findAllName() {
        return setMealDao.findAllName();
    }

    @Override
    public List<Map<String, Object>> findSetmealCountByOrder() {
        return setMealDao.findSetmealCountByOrder();
    }
}
